import threading
import tkinter as tk
from tkinter import scrolledtext
from tkinter import ttk,Toplevel
from pyportscanner import pyscanner
import py_config
from configparser import ConfigParser
class ConfigWin(tk.Toplevel):
    def __init__(self, master,cfg:ConfigParser):
        tk.Toplevel.__init__(self, master=master)
        self.config = cfg
        self.title("端口监听查询")
        # self.update_frequency()
        self.geometry('400x500')
        self.init_ui()


    def on_toplevel_closing(self):
        pass

    def init_ui(self):
        window=self
        label = tk.Label(window, text="请输入要检测的ip（例如：192.168.0.1）:", font=("Arial", 12))
        label.pack(pady=10)
        entry_text_var = tk.StringVar()  # 创建StringVar变量
        entry_text_var.set(self.config.get('PortScan','address'))  # 设置初始值
        self.entry = tk.Entry(window, width=20, justify='center', font=('Arial', 12), textvariable=entry_text_var)
        self.entry.pack()
        label = tk.Label(window, text="请输入要检测的端口(例如：1或1-80或t80):", font=("Arial", 12))
        label.pack(pady=10)
        port_var = tk.StringVar()  # 创建StringVar变量
        port_var.set(self.config.get('PortScan','port_scope'))  # 设置初始值
        self.port=tk.Entry(window,width=20,justify='center', font=('Arial', 12), textvariable=port_var)
        self.port.pack(pady=10)

        self.btn_detect = tk.Button(window, text="检测", command=lambda:self.check_port_thread(entry_text_var.get(),port_var.get()), font=("Arial", 12))
        self.btn_detect.pack(pady=10)
        self.progress_bar = ttk.Progressbar(window, orient=tk.HORIZONTAL, length=200, mode='determinate')
        # self.progress_bar.pack(pady=10)
        self.output = scrolledtext.ScrolledText(window, width=40, height=50, font=("Arial", 12))
        self.output.pack(pady=10)

    def check_port_thread(self,ip,target_ports):
        ports=None
        if 't' in target_ports:
            ports=int(target_ports[1:])
        elif '-' in target_ports:
            nums=target_ports.split('-')
            start=int(nums[0])
            end=int(nums[1])
            ports=list(range(start,end))
        else:
            ports=[int(target_ports)]
        self.config.set('PortScan','address',ip)
        self.config.set('PortScan', 'port_scope', target_ports)
        py_config.write_config(self.config,'./pingtool.ini')
        thread=threading.Thread(target=lambda:self.check_port_thread_impl(ip, ports))
        thread.start()

    def check_port_thread_impl(self,ip,ports):
        self.btn_detect.configure(state=tk.DISABLED)
        scanner = pyscanner.PortScanner(target_ports=ports, verbose=False,timeout=1,thread_limit=200)
        host_name = ip
        message = 'put whatever message you want here'
        '''
        output contains a dictionary of {port:status} pairs
        in which port is the list of ports we scanned 
        and status is either 'OPEN' or 'CLOSE'
        '''
        res = scanner.scan(host_name, message)
        ok_port=[]
        for item in res:
            if(res[item]!='CLOSE'):
                ok_port.append(item)
        self.show_data(sorted(ok_port))
        self.btn_detect.configure(state=tk.NORMAL)

    def show_data(self,items):
        self.progress_bar['maximum'] = len(items)
        self.progress_bar['value'] = 0
        self.output.delete(1.0, tk.END)
        for i in items:
            fg_color = "green"
            output=self.output
            output.tag_configure(fg_color, foreground=fg_color)  # 创建颜色标签
            output.tag_configure(fg_color, foreground=fg_color)  # 创建颜色标签
            output.insert(tk.END, '{0}:{1}\n'.format(i, 'OPEN'), fg_color)
            output.see(tk.END)
            self.progress_bar['value'] += 1
            self.update_idletasks()

if __name__=='__main__':
    root = tk.Tk()
    root.geometry("400x500")
    ui=ConfigWin(root)
    ui.mainloop()